#version 450 core

layout(location = 0) in vec3 aPostion;
layout(location = 1) in vec3 aNormal;
layout(location = 2) in vec2 aUv;
layout(location = 3) in uint aPackedData;

uniform mat4 uMVP;
uniform mat4 uView;
uniform mat4 uModel;

out vec4 fragPos;
out vec2 fragUv;
out flat vec2 fragTexIdx;
out flat uint fragAnimSize;
out vec3 fragNormal;
out float fragOcclusionLighting;
out vec3 fragLighting;

void main() {
    fragPos = vec4(aPostion, 1.0);
    fragUv = aUv / 16.0f;

    uint xTexIdx = bitfieldExtract(aPackedData, 0, 6);
    uint yTexIdx = bitfieldExtract(aPackedData, 6, 6);
    fragTexIdx = vec2(xTexIdx, yTexIdx);

    uint animSize = bitfieldExtract(aPackedData, 12, 5);
    fragAnimSize = animSize + 1;

    uint occlusionLevel = bitfieldExtract(aPackedData, 17, 2);
    fragOcclusionLighting = (0.75f + (0.08f * occlusionLevel));

    uint vertexLightLevel = bitfieldExtract(aPackedData, 19, 4);
    // fragLighting = vec3(0.7f, 0.65f, 0.32f) * ((vertexLightLevel + 5.0f) / 20.0f);
    fragLighting = vec3(0.98f, 0.93f, 0.32f) * ((vertexLightLevel + 5.0f) / 20.0f);

    fragNormal = aNormal * 0.5 + 0.5;

    gl_Position = uMVP * fragPos;

    fragPos.xyz = (uView * uModel * fragPos).xyz / 256.0;
}